package com.fumin.common;

import com.fumin.util.JsonMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * Http请求的前后监听类
 * @Author xiayuxuanmin
 * @Date 2019/10/21
 * @Description
 */
@Slf4j
public class HttpInterceptor extends HandlerInterceptorAdapter {

    public static String START_TIME = "requestStartTime";//设置变量作为key值

    /**
     * 任何请求处理之前调用
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String url = request.getRequestURI().toString();
        Map parameterMap = request.getParameterMap();
        log.info("request start... url:{},parameterMap:{}",url, JsonMapper.obj2String(parameterMap));
        long start = System.currentTimeMillis();//记录请求开始处理的时间
        request.setAttribute(START_TIME,start);
        return true;
    }

    /**
     * 任何请求正常处理之后调用
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        String url = request.getRequestURI().toString();
        Map parameterMap = request.getParameterMap();
        log.info("request correct finished... url:{},parameterMap:{}",url, JsonMapper.obj2String(parameterMap));
//        Long start = (Long)request.getAttribute(START_TIME);
//        Long end = System.currentTimeMillis();
//        log.info("request 花费时间... url:{},cost:{}",url, end-start);//输出处理的请求时间
        //在触发了该方法之后,会立即触发afterCompletion方法,两者的时间基本一样,所以这里可以不再监控花费的时间,而是放在afterCompletion中

        removeThreadLocal();
    }

    /**
     * 任何请求处理之后调用,和postHandle的区别是:任何情况,只要请求处理完了,都会调用,即使抛出异常,也会调用该方法
     * @param request
     * @param response
     * @param handler
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        String url = request.getRequestURI().toString();
        Map parameterMap = request.getParameterMap();
        log.info("request finally finished... url:{},parameterMap:{}",url, JsonMapper.obj2String(parameterMap));
        Long start = (Long)request.getAttribute(START_TIME);
        Long end = System.currentTimeMillis();
        log.info("request 花费时间... url:{},cost:{}",url, end-start);//输出处理的请求时间

        removeThreadLocal();
    }

    /**
     * 清除ThreadLocal
     */
    public void removeThreadLocal(){
        RequestHolder.remove();
    }
}
